// Copyright (C) 2005-2008 Jae Stutzman (jaebird@gmail.com)
//
// This file is part of MrPodder.
//
// MrPodder is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// MrPodder is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with MrPodder.  If not, see <http://www.gnu.org/licenses/>.

using System;
using System.IO;
using EnterpriseDT.Net.Ftp;

namespace MediaHandler
{
	public delegate void PercentageEventDelegate(object sender, PercentageEventArgs e);

	public class PercentageEventArgs
	{
		private int percentage;

		public int Percentage
		{
			get { return percentage; }
		}

		public PercentageEventArgs(int percentage)
		{
			this.percentage = percentage;
		}
	}

	/// <summary>
	/// Summary description for Class1.
	/// </summary>
	public class Publisher
	{
		private const char ftpDirSeparator = '/';

		public event PercentageEventDelegate PercentageEvent;

		private readonly string host;
		private readonly string user;
		private readonly string password;
		private readonly string uploadDirectory;
		
		private bool success = false;

		public Publisher(string host, string user, string password, string uploadDirectory)
		{
			this.host = host;
			this.user = user;
			this.password = password;

			// for ftp the slash is always / not \ like on windows..
			this.uploadDirectory = uploadDirectory.Replace('\\', ftpDirSeparator);
		}

		public bool Upload(string filename, out string message)
		{
			return Upload(filename, filename, out message);
		}

		public bool Upload(string localFilename, string remoteFilename, out string message)
		{
			success = false;
			message = string.Empty;

			try
			{
				FTPClient ftp = new FTPClient();
				ftp.TransferCompleteEx += new TransferHandler(ftp_TransferCompleteEx);
				ftp.BytesTransferred += new BytesTransferredHandler(ftp_BytesTransferred);
				ftp.RemoteHost = host;

				try
				{
					ftp.Connect();
				}
				catch (Exception connectException)
				{
					throw new Exception("Server Cannot Be Found");
				}

				try
				{
					// login
					ftp.Login(user, password);
				}
				catch (Exception loginException)
				{
					throw new Exception("User/Password Incorrect");
				}

				// set up passive ASCII transfers
				ftp.ConnectMode = FTPConnectMode.PASV;
				ftp.TransferType = FTPTransferType.BINARY;

				try
				{
					ftp.ChDir(uploadDirectory);
				}
				catch
				{
					// try to create the dir structure
					CreateUploadStructure(ftp, uploadDirectory);
					//ftp.ChDir(uploadDirectory);
				}

				// copy file to server 
				ftp.Put(localFilename, Path.GetFileName(remoteFilename));
				ftp.Quit();
			}
			catch (Exception e)
			{
				message = e.Message;
			}

			return success;
		}

		private void CreateUploadStructure(FTPClient ftp, string uploadDirectory)
		{
			string currentDir = ftp.Pwd();
			string[] splits = uploadDirectory.Split(ftpDirSeparator);
			foreach (string split in splits)
			{
				try
				{
					ftp.MkDir(split);
				}
				catch { }

				ftp.ChDir(split);
			}
		}

		void ftp_BytesTransferred(object sender, BytesTransferredEventArgs e)
		{
			if (PercentageEvent != null)
			{
				PercentageEvent(this, new PercentageEventArgs((int)((e.ByteCount / e.FileSize) * 100)));
			}
		}

		private void ftp_TransferCompleteEx(object sender, TransferEventArgs e)
		{
			success = true;
		}
	}
}
